using System;
using System.Xml;
using System.Web;


namespace umlungu.engineX.webX {
	/// <summary>
	/// umlungu engineX web framework, site class.
	/// </summary>
	public class contentX
	{
		/// <summary>
		/// Local objects and properties
		/// </summary>
		private bool debug;
		private System.Web.UI.Page page;
		private profileX profile;
		private siteX site;
		private XmlDocument xml;
		private XmlElement link, content, pagexml, title, source;
		private string pathroot;
		
		/// <summary>
		/// Public properties
		/// </summary>
		public XmlDocument Xml	{	get	{ return xml; }			set { xml = value; } }
		public XmlElement Link	{	get	{ return link; }		set { link = value; } }
		public XmlElement Page	{	get	{ return pagexml; }		set { pagexml = value; } }
		public XmlElement Content	{	get	{ return content; }		set { content = value; } }
		
		public string Title		{	get	{ return title.InnerText; }						set { title.InnerText = value; } }
		public string Name		{	get	{ return(source.GetAttribute("name")); }		set { source.SetAttribute("name", value); } }
		public string Type		{	get	{ return(source.GetAttribute("type")); }		set { source.SetAttribute("type", value); } }
		public string Section	{	get	{ return(source.GetAttribute("section")); }		set { source.SetAttribute("section", value); } }
		public string Subsect	{	get	{ return(source.GetAttribute("subsect")); }		set { source.SetAttribute("subsect", value); } }
		public string Process	{	get	{ return(source.GetAttribute("process")); }		set { source.SetAttribute("process", value); } }
		public string Filename	{	get	{ return(source.GetAttribute("filename")); }	set { source.SetAttribute("filename", value); } }
		public string Linkref	{	get	{ return(link.GetAttribute("name")); }			set { link.SetAttribute("name", value); } }
		public string Group		{	get	{ return(link.GetAttribute("group")); }			set { link.SetAttribute("group", value); } }
		public string Device	{	get	{ return(link.GetAttribute("device")); }		set { link.SetAttribute("device", value); } }
		public string Mode		{	get	{ return(link.GetAttribute("mode")); }			set { link.SetAttribute("mode", value); } }
		
		public bool RequireGloss	{	get { return(pagexml.GetAttribute("glossary") == "yes"); } 		set { pagexml.SetAttribute("glossary", value? "yes" : "no"); } }
		public bool RequireRelinfo	{	get { return(pagexml.GetAttribute("relinfo") == "yes"); } 		set { pagexml.SetAttribute("relinfo", value? "yes" : "no"); } }
		public bool IsForm			{	get { return(pagexml.SelectSingleNode("form or confirms") != null); }}
		public bool Default			{	get { return(site.HomeLink == link.GetAttribute("name")); } }
		
		public string Root		{	get	{ return pathroot; }	set { pathroot = value; } }
		public string FilePath	{	get { return (String.Concat(pathroot, Section, "\\", Subsect, "\\", Process, (Process == "")? "" : "\\", Filename)); }}
		
		#region Public methods
		/// <summary>Constructor</summary>
		public contentX() {	// this constructor is here to allow serialisation
			debug = false;
		}
		public contentX(System.Web.UI.Page thispage, bool wantdebug) {
			page = thispage;
			debug = wantdebug;
		}
		public contentX(System.Web.UI.Page thispage, bool wantdebug, siteX thissite, profileX prof) {
			site = thissite;
			page = thispage;
			debug = wantdebug;
			pathroot = (site.ContentDir != "")? String.Concat(site.ContentDir, "\\") : "";
			profile = prof;
			initialise();
		}
		/// <summary>
		/// Method description
		/// </summary>
		public void FromUrl() {
			_Debug("FromUrl", "getQuery('type'):", getQuery("type", "page"));
			setLink(getQuery("link", site.HomeLink), getQuery("type", "page"), getQuery("name"), getQuery("device", "screen"), getQuery("mode", "view"));
			setSource(getQuery("section"), getQuery("subsect"), getQuery("process"), getQuery("filename"));
			if (Section == "" || Subsect == "" || Process == "" || Filename == "")
				getLinks();
			// load file for forms and services
			_Debug("FromUrl", "Type:", Type, " Name:", Name, " Linkref:", Linkref, " Filename:", Filename);
			if ((Type == "service" || Type == "form") && Section != "" && Subsect != "")
				load();
			_Debug("FromUrl", "xml", xml.DocumentElement.OuterXml);
		}
		/// <summary>
		/// Method description
		/// </summary>
		public void FromSession() {
			xml = (XmlDocument) page.Session["x_content_xml"];
			_Debug("FromSession", "xml", xml.OuterXml);
			initialise(xml);
		}
		/// <summary>
		/// Method description
		/// </summary>
		public void ToSession() {
			page.Session["x_content_xml"] = xml;
		}
		/// <summary>
		/// Load:: Method to load the XML content
		/// </summary>
		public void Load() {
			_Debug("Load", "Type:", Type);
			try {
				if (Type == "service") {	// do nothing ?
					_Debug("Load", "(service):", FilePath);
					/*
					if (page.Session["x_xml"] != null)
						xml = (XmlDocument) page.Session["x_xml"];
					else
						load((string) page.Session["x_contxml"]);
					*/
				} else if (Type != "exhtml") {	// load content file
					load();
				}
			} catch (System.Exception e) {
				exceptionX exceptX = new exceptionX("Load", "error loading xml", e);
				xml = exceptX.Xml;
			}
		}
		/// <summary>
		/// Method description
		/// </summary>
		public void SetPage(string section, string subsect, string process, string filename) {
			set("page", "", section, subsect, process, filename);
		}
		public void SetPage(string title, string link, string section, string subsect, string process, string filename) {
			set(title, link, "page", "", section, subsect, process, filename);
		}
		/// <summary>
		/// Method description
		/// </summary>
		public void Set(string contxml) {
			xml.InnerXml = contxml;
		}
		public void Set(XmlDocument contxml) {
			xml = contxml;
		}
		/// <summary>
		/// Method description
		/// </summary>
		public void SetXml(string contxml) {
			content.InnerXml = contxml;
		}
		public void SetXml(XmlDocument contxml) {
			content.InnerXml = contxml.DocumentElement.OuterXml;
		}
		public void Save() {
			if (debug)
				xml.Save(page.Server.MapPath(String.Concat(FilePath, "_dbg.xml")));
		}
		#endregion

		#region Protected methods
		/// <summary>
		/// Method description
		/// </summary>
		protected void _Debug(string label, params string[] outparam) {
			if (debug) {
				page.Response.Write("\n<!-- contentX.");
				page.Response.Write(label);
				page.Response.Write("::\n");
				for (int i=0; i < outparam.Length; i++)
					page.Response.Write(outparam[i]);
				page.Response.Write("\n-->\n");
			}
		}
		#endregion

		#region Private methods
		/// <summary>
		/// Method description
		/// </summary>
		private void initialise() {
			xml = new XmlDocument();
			XmlDocument contxml = (XmlDocument) page.Application[String.Concat(site.SiteID, "_x_content_xml")];
			xml.LoadXml(contxml.OuterXml);
			initialise(xml);
		}
		private void initialise(XmlDocument contxml) {
			link = (XmlElement) contxml.SelectSingleNode("/contentX/link");
			content = (XmlElement) contxml.SelectSingleNode("/contentX/content");
			pagexml = (XmlElement) content.SelectSingleNode("page");
			title = (XmlElement) link.SelectSingleNode("title");
			source = (XmlElement) link.SelectSingleNode("source");
		}
		/// <summary>
		/// Method description
		/// </summary>
		private void setSource(string section, string subsect, string process, string filename) {
			Process = process;
			Section = section;
			Subsect = subsect;
			Filename = filename;
		}
		private void setSource(string type, string section, string subsect, string process, string filename) {
			Type = type;
			setSource(section, subsect, process, filename);
		}
		/// <summary>
		/// Method description
		/// </summary>
		private void setLink(string link, string type, string name, string device, string mode) {
			Linkref = link;
			Type = type;
			Name = name;
			Device = device;
			Mode = mode;
		}
		/// <summary>
		/// Method description
		/// </summary>
		private void set(string type, string name, string section, string subsect, string process, string filename) {
			Type = type;
			Name = name;
			setSource(section, subsect, process, filename);
		}
		private void set(string title, string lnk, string type, string name, string section, string subsect, string process, string filename) {
			Title = title;
			Linkref = lnk;
			Type = type;
			Name = name;
			setSource(section, subsect, process, filename);
		}
		/// <summary>
		/// Method description
		/// </summary>
		private string getQuery(string thisparam) {
			return(getQuery(thisparam, ""));
		}
		private string getQuery(string thisparam, string defval) {
			string thisparamstr = defval;
			string thisquery = page.Request.QueryString[thisparam];
			if (thisquery != "" && thisquery != null)
				thisparamstr = page.Request.QueryString[thisparam];
			return(thisparamstr);
		}
		/// <summary>
		/// Method description
		/// </summary>
		private void getLinks() {
			bool allow;
			XmlDocument lnkxml = (XmlDocument) page.Application[site.LinksTemplate];
			if (lnkxml == null)
				throw(new exceptionX("content.getLinks", "links xml not loaded"));
			XmlElement lnknode = (XmlElement) lnkxml.DocumentElement.SelectSingleNode(String.Concat("//lnk[@name = '", Linkref, "']"));
			if (lnknode != null) {
				if (profile != null) {
					Group = lnknode.GetAttribute("group");
					_Debug("getLinks", "Group:", Group, " User Group:", profile.Group, " (test:", Group.IndexOf(profile.Group).ToString(), ")");
					if (Group == "all")
						allow = true;
					else if (Group.IndexOf(profile.Group) >= 0)
						allow = true;
					else if (profile.Token == "" && Group == "public")
						allow = true;
					else if (profile.Token == "" && Device != "screen") // ie when doing a data download or saving an email as file to disk
						allow = true;
					else
						allow = false;
				} else	// no profile check
					allow = true;
					
				if (allow) {
					setSource(lnknode.GetAttribute("sect"), lnknode.GetAttribute("sub"), lnknode.GetAttribute("proc"), lnknode.GetAttribute("file"));
					XmlNode promptnode = lnknode.SelectSingleNode("prompt");
					Title = (promptnode != null)? promptnode.InnerText : "";
				} else {
					set("Error", "error_site_noaccess", "page", "", "errors", "site", "", "noaccess");
				}
			} else {
				set("Error", "error_site_nolink", "page", "", "errors", "site", "", "nolink");
			}
		}
		/// <summary>
		/// Method description
		/// </summary>
		private void load(string xmlstr) {
			_Debug("load", "(xmlstr):", FilePath);
			pagexml.InnerXml = xmlstr;
		}
		private void load() {
			_Debug("load", "FilePath:", FilePath);
			XmlDocument thisxml = new XmlDocument();
			thisxml.Load(page.Server.MapPath(FilePath + ".xml"));
			loadpage((XmlElement) thisxml.SelectSingleNode("/content/page"));
		}
		/// <summary>
		/// Method description
		/// </summary>
		private void loadpage(XmlElement pgelem) {
			pagexml.InnerXml = pgelem.InnerXml;
			foreach (XmlAttribute pageattr in pagexml.Attributes) {
				pageattr.Value = (pgelem.GetAttribute(pageattr.Name) != "")? pgelem.GetAttribute(pageattr.Name) : pageattr.Value;
			}
		}
		#endregion
	}
}
